package com.lhkj.ct.meta.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lhkj.ct.base.constants.ConfigConstants;
import com.lhkj.ct.base.constants.SystemConstants;
import com.lhkj.ct.base.enums.DeleteStatus;
import com.lhkj.ct.base.enums.ReturnStatus;
import com.lhkj.ct.base.exception.BusinessException;
import com.lhkj.ct.base.mybatis.extension.service.impl.IServiceImpl;
import com.lhkj.ct.base.utils.Asserts;
import com.lhkj.ct.base.utils.ShiroUtil;
import com.lhkj.ct.meta.admin.mapper.SysDeptMapper;
import com.lhkj.ct.meta.admin.mapper.SysEmployeeMapper;
import com.lhkj.ct.meta.admin.model.dto.EmpPageQuery;
import com.lhkj.ct.meta.admin.model.entity.TblDepartment;
import com.lhkj.ct.meta.admin.model.entity.TblEmployee;
import com.lhkj.ct.meta.admin.model.vo.EmpPageVo;
import com.lhkj.ct.meta.admin.model.vo.UserProfile;
import com.lhkj.ct.meta.admin.service.SysConfigService;
import com.lhkj.ct.meta.admin.service.SysEmployeeService;
import com.lhkj.ct.meta.admin.service.UserRoleService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.Serializable;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author jobob
 * @since 2023-08-23
 */
@Service
public class SysEmployeeServiceImpl extends IServiceImpl<SysEmployeeMapper, TblEmployee> implements SysEmployeeService {

    private final int hashIterations = SystemConstants.HASH_ITERATIONS;

    @Resource
    private UserRoleService userRoleService;

    @Resource
    private SysDeptMapper deptMapper;

    @Resource
    private SysConfigService sysConfigService;

    @Override
    public TblEmployee getById(Serializable id) {
        TblEmployee target = getBaseMapper().selectById(id);
        if (null != target) {
            target.setRoleIds(userRoleService.selectRoleIdsByUser(target.getId()));
        }
        return target;
    }

    @Override
    public UserProfile getUserProfile(String userId) {
        return getBaseMapper().getUserProfile(userId);
    }

    @Override
    public int updateUserProfile(TblEmployee user) {
        LambdaUpdateWrapper<TblEmployee> updateWrapper = new LambdaUpdateWrapper<TblEmployee>()
                .set(StringUtils.isNotBlank(user.getEmpName()), TblEmployee::getEmpName, user.getEmpName())
                .set(StringUtils.isNotBlank(user.getDutiesName()), TblEmployee::getDutiesName, user.getDutiesName())
                .set(TblEmployee::getContactPhone, user.getContactPhone())
                .set(TblEmployee::getAddress, user.getAddress())
                .set(TblEmployee::getEmpProfile, user.getEmpProfile())
                .eq(TblEmployee::getId, user.getId());
        return getBaseMapper().update(null, updateWrapper);
    }

    @Override
    public int resetUserPwd(String oldPassword, String newPassword) {
        TblEmployee currentUser = getBaseMapper().selectById(ShiroUtil.getAuthUserInfo().getUserId());
        if (null == currentUser) {
            return 0;
        }
        oldPassword = new Md5Hash(oldPassword, SystemConstants.ACCOUNT_SALT, hashIterations).toHex();
        if (!StringUtils.equals(currentUser.getPassword(), oldPassword)) {
            throw new BusinessException(ReturnStatus.SC_BAD_REQUEST, "修改密码失败，旧密码错误");
        }
        newPassword = new Md5Hash(newPassword, SystemConstants.ACCOUNT_SALT, hashIterations).toHex();
        if (StringUtils.equals(oldPassword, newPassword)) {
            throw new BusinessException(ReturnStatus.SC_BAD_REQUEST, "新密码不能与旧密码相同");
        }
        currentUser.setPassword(newPassword);
        return getBaseMapper().updateById(currentUser);
    }

    @Override
    public boolean updateUserAvatar(String userId, String avatarUrl) {
        TblEmployee user = new TblEmployee();
        user.setId(userId);
        user.setEmpAvatar(avatarUrl);
        return getBaseMapper().updateById(user) > 0;
    }

    @Override
    public int save(TblEmployee employee) {
        // fixme 校验科室和机构关系
        TblDepartment department = deptMapper.selectById(employee.getDeptId());
        Asserts.assertFalse(null == department, "科室不存在或标识符无效!");
        Asserts.assertTrue(StringUtils.equals(department.getOrganId(), employee.getOrganId()), "科室与机构不匹配!");
        Asserts.assertTrue(checkEmpNoUnique(employee), "该机构已存在工号：" + employee.getEmpNo());
        if (StringUtils.isBlank(employee.getId())) {
            String defaultPwd = sysConfigService.selectConfigByKey(ConfigConstants.INIT_PASSWORD);
            // 密码加密
            String credentials = new Md5Hash(defaultPwd, SystemConstants.ACCOUNT_SALT, hashIterations).toHex();
            employee.setPassword(credentials);
        }
        int res = this.saveOrUpdate(employee);
        if (res > 0) {
            userRoleService.saveUserRoles(employee.getId(), employee.getRoleIds());
        }
        return res;
    }

    @Override
    public boolean checkEmpNoUnique(TblEmployee employee) {
        TblEmployee target = getBaseMapper().selectOne(new LambdaQueryWrapper<TblEmployee>()
                .select(TblEmployee::getId)
                .eq(TblEmployee::getEmpNo, employee.getEmpNo())
                .eq(TblEmployee::getDelFlag, DeleteStatus.NORMAL)
                .eq(TblEmployee::getOrganId, employee.getOrganId())
        );
        return target == null || StringUtils.equals(target.getId(), employee.getId());
    }

    @Override
    public String resetPassword(String userId) {
        TblEmployee target = getById(userId);
        Asserts.assertFalse(null == target, "员工不存在或数据标识符无效！");
        String initPassword = sysConfigService.selectConfigByKey(ConfigConstants.INIT_PASSWORD);
        String encryptPwd = new Md5Hash(initPassword, SystemConstants.ACCOUNT_SALT, hashIterations).toHex();
        getBaseMapper().update(null,
                new UpdateWrapper<TblEmployee>().lambda()
                        .set(TblEmployee::getPassword, encryptPwd)
                        .eq(TblEmployee::getId, userId));
        return initPassword;
    }

    @Override
    public IPage<EmpPageVo> selectEmpPage(EmpPageQuery pageQuery) {
        Page<TblEmployee> page = generatePage(pageQuery);
        return getBaseMapper().selectEmpPage(page, pageQuery);
    }

    @Override
    public IPage<EmpPageVo> selectEmpOptions(EmpPageQuery pageQuery) {
        Page<TblEmployee> page = generatePage(pageQuery);
        return getBaseMapper().selectEmpOptions(page, pageQuery);
    }

    @Override
    public int updateUserStatus(TblEmployee employee) {
        LambdaUpdateWrapper<TblEmployee> updateWrapper = new LambdaUpdateWrapper<TblEmployee>()
                .set(TblEmployee::getEmpStatus, employee.getEmpStatus())
                .eq(TblEmployee::getId, employee.getId());
        return getBaseMapper().update(null, updateWrapper);
    }
}
